package com.liqi.web.controller.remote;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.liqi.common.utils.DateUtils;
import com.liqi.common.utils.mqtt.MqttConfig;
import com.liqi.common.utils.mqtt.MqttPushClient;
import com.liqi.common.utils.uuid.GenerateCodeUtils;
import com.liqi.deployment.domain.DvDeployment;
import com.liqi.deployment.service.IDvDeploymentService;
import com.liqi.device.domain.DvRemoteScreenshot;
import com.liqi.device.service.IDvRemoteScreenshotService;
import com.liqi.remote.domain.DvRemoteCommand;
import com.liqi.remote.domain.DvSaveLogFile;
import com.liqi.remote.domain.dto.RemoteDto;
import com.liqi.remote.domain.dto.RemoteLogDto;
import com.liqi.remote.service.IDvRemoteCommandService;
import com.liqi.remote.service.IDvSaveLogFileService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import com.liqi.common.core.controller.BaseController;
import com.liqi.common.core.domain.R;
import com.liqi.remote.service.RemoteService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

/**
 * 远程操作命令 Controller
 *
 * @author xiaoli
 * @date 2022-02-14
 */
@Slf4j
@Api(tags = "远程操作命令")
@RestController
@RequestMapping("/remote")
public class RemoteController extends BaseController
{


    @Autowired
    private MqttConfig mqttConfig;
    @Autowired
    private HttpServletRequest request;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private RemoteService remoteService;

    @Autowired
    private IDvRemoteCommandService dvRemoteCommandService;

    @Autowired
    private IDvDeploymentService dvDeploymentService;
    @Autowired
    private IDvSaveLogFileService dvSaveLogFileService;
    @Autowired
    private IDvRemoteScreenshotService dvRemoteScreenshotService;
    @Value("${remote.port}")
    private String IP_PORT;

    // 1、远程关机
    @ApiOperation("远程关机")
    @PostMapping("/shutdown")
    public R shutdown(@RequestBody List<RemoteDto> remoteDteList){
        log.info("远程关机 请求参数 remoteDteList：{}", JSONObject.toJSONString(remoteDteList));
        remoteDteList.forEach(m ->{
            // 流水号
            m.setMessageCode(GenerateCodeUtils.getSequnce());
            m.setCommandType(2);
            String deviceId = m.getDeviceId();
            MqttPushClient client = mqttConfig.getDeviceIdMqttPushClient(deviceId);
            String json = JSON.toJSONString(m);
            R publish = client.publish(0, false, deviceId, json);
            DvRemoteCommand dvRemoteCommand = new DvRemoteCommand();
            long issuedStatus = 1L;
            if (!publish.isSuccess()){
                issuedStatus = -1L;
                dvRemoteCommand.setIssuedErrrorMessage("远程关机消息推送失败");
            }
            String ipAddress = m.getIpAddress();
            DvDeployment deployment = dvDeploymentService.getByDeviceId(deviceId);
            String deptId = deployment.getDeptId();
            dvRemoteCommand.setDeviceId(deviceId);
            dvRemoteCommand.setCommandType(2L);
            dvRemoteCommand.setIpAddress(ipAddress);
            dvRemoteCommand.setIssuedStatus(issuedStatus);
            dvRemoteCommand.setIssuedTime(DateUtils.getNowDate());
            dvRemoteCommand.setStatus(0);
            dvRemoteCommand.setDeptId(deptId);
            dvRemoteCommandService.insertDvRemoteCommand(dvRemoteCommand);
        });
        return R.ok("远程关机消息已经推送",null);
    }
    // 1、远程关机
//    @ApiOperation("远程关机")
//    @PostMapping("/shutdown")
//    public R shutdown(@RequestBody List<RemoteDto> remoteDteList){
//        log.info("远程关机 请求参数 remoteDteList：{}", JSONObject.toJSONString(remoteDteList));
//        List<String> errorList = new ArrayList<>();
//        try {
//            for (RemoteDto remoteDto : remoteDteList) {
//                DvRemoteCommand dvRemoteCommand = new DvRemoteCommand();
//                String ipAddress = remoteDto.getIpAddress();
//                String deviceId = remoteDto.getDeviceId();
//                Integer wait = remoteDto.getWait();
//                ipAddress = ipAddress + ":" + IP_PORT;
//                String reqData = remoteService.shutdown(ipAddress,deviceId, wait);
//                JSONObject object = JSONObject.parseObject(reqData);
//                if ((Integer) object.get("code") != 200) {
//                    logger.info("远程关机失败：" + reqData);
//                    errorList.add(remoteDto.getDeviceId());
//                    dvRemoteCommand.setIssuedStatus(-1L);
//                    dvRemoteCommand.setIssuedErrrorMessage(reqData);
//                }
//                DvDeployment deployment = dvDeploymentService.getByDeviceId(deviceId);
//                String deptId = deployment.getDeptId();
//                dvRemoteCommand.setDeviceId(deviceId);
//                dvRemoteCommand.setCommandType(2L);
//                dvRemoteCommand.setIpAddress(ipAddress);
//                dvRemoteCommand.setIssuedStatus(1L);
//                dvRemoteCommand.setIssuedTime(DateUtils.getNowDate());
//                dvRemoteCommand.setStatus(0);
//                dvRemoteCommand.setDeptId(deptId);
//                dvRemoteCommandService.insertDvRemoteCommand(dvRemoteCommand);
//            }
//        } catch (Exception e) {
//            logger.error("远程关机失败：" + e);
//            return R.fail("远程关机失败：请联系工作人员");
//        }
//        if (errorList.size() != 0) {
//            return R.fail(JSONObject.toJSONString(errorList));
//        }
//        return R.ok();
//    }

    // 2、远程重启
//    @ApiOperation("远程重启")
//    @PostMapping("/")
//    public R restart(@RequestBody List<RemoteDto> remoteDteList){
//        log.info("远程重启 请求参数 remoteDteList：{}", JSONObject.toJSONString(remoteDteList));
//        List<String> errorList = new ArrayList<>();
//        try {
//            for (RemoteDto remoteDto : remoteDteList) {
//                DvRemoteCommand dvRemoteCommand = new DvRemoteCommand();
//                String ipAddress = remoteDto.getIpAddress();
//                String deviceId = remoteDto.getDeviceId();
//                Integer wait = remoteDto.getWait();
//                ipAddress = ipAddress + ":" + IP_PORT;
//                String reqData = remoteService.restart(ipAddress, deviceId, wait);
//                JSONObject object = JSONObject.parseObject(reqData);
//                if ((Integer) object.get("code") != 200) {
//                    logger.info("远程重启失败：" + reqData);
//                    errorList.add(remoteDto.getDeviceId());
//                    dvRemoteCommand.setIssuedStatus(-1L);
//                    dvRemoteCommand.setIssuedErrrorMessage(reqData);
//                }
//                DvDeployment deployment = dvDeploymentService.getByDeviceId(deviceId);
//                String deptId = deployment.getDeptId();
//                dvRemoteCommand.setDeviceId(deviceId);
//                dvRemoteCommand.setCommandType(3L);
//                dvRemoteCommand.setIpAddress(ipAddress);
//                dvRemoteCommand.setIssuedStatus(1L);
//                dvRemoteCommand.setIssuedTime(DateUtils.getNowDate());
//                dvRemoteCommand.setStatus(0);
//                dvRemoteCommand.setDeptId(deptId);
//                dvRemoteCommandService.insertDvRemoteCommand(dvRemoteCommand);
//            }
//        } catch (Exception e) {
//            logger.error("远程重启失败：" + e);
//            return R.fail("远程重启失败：请联系工作人员");
//        }
//        if (errorList.size() != 0) {
//            return R.fail(JSONObject.toJSONString(errorList));
//        }
//        return R.ok();
//    }
    // 2、远程重启
    @ApiOperation("远程重启")
    @PostMapping("/restart")
    @Transactional
    public R restart(@RequestBody List<RemoteDto> remoteDteList) {
        log.info("远程重启 请求参数 remoteDteList：{}", JSONObject.toJSONString(remoteDteList));
        remoteDteList.forEach(m ->{
            // 流水号
            m.setMessageCode(GenerateCodeUtils.getSequnce());
            m.setCommandType(3);
            String deviceId = m.getDeviceId();
            MqttPushClient client = mqttConfig.getDeviceIdMqttPushClient(deviceId);
            String json = JSON.toJSONString(m);
            R publish = client.publish(0, false, deviceId, json);
            DvRemoteCommand dvRemoteCommand = new DvRemoteCommand();
            long issuedStatus = 1L;
            if (!publish.isSuccess()){
                issuedStatus = -1L;
                dvRemoteCommand.setIssuedErrrorMessage("远程重启消息推送失败");
            }
            String ipAddress = m.getIpAddress();
            DvDeployment deployment = dvDeploymentService.getByDeviceId(deviceId);
            String deptId = deployment.getDeptId();
            dvRemoteCommand.setDeviceId(deviceId);
            dvRemoteCommand.setCommandType(3L);
            dvRemoteCommand.setIpAddress(ipAddress);
            dvRemoteCommand.setIssuedStatus(issuedStatus);
            dvRemoteCommand.setIssuedTime(DateUtils.getNowDate());
            dvRemoteCommand.setStatus(0);
            dvRemoteCommand.setDeptId(deptId);
            dvRemoteCommandService.insertDvRemoteCommand(dvRemoteCommand);
        });
        return R.ok("远程重启消息已经推送",null);
    }


    // 3、远程拉取日志
    @ApiOperation("远程拉取日志")
    @PostMapping("/remotegetLogFile")
    public R getLogFile(@RequestBody RemoteLogDto remoteLogDtoList){
        log.info("远程拉取日志 请求参数 remoteLogDtoList：{}", JSONObject.toJSONString(remoteLogDtoList));
//        try {
            // 流水号
        	String messageCode = GenerateCodeUtils.getSequnce();
        	remoteLogDtoList.setMessageCode(messageCode);
        	remoteLogDtoList.setCommandType(5);
            String deviceId = remoteLogDtoList.getDeviceId();
            MqttPushClient client = mqttConfig.getDeviceIdMqttPushClient(deviceId);
            String json = JSON.toJSONString(remoteLogDtoList);
            client.publish(0, false, deviceId, json);
            DvRemoteCommand dvRemoteCommand = new DvRemoteCommand();
            String ipAddress = remoteLogDtoList.getIpAddress();
            //    Integer logDateSpan = remoteLogDtoList.getLogDateSpan();
                ipAddress = ipAddress + ":" + IP_PORT;
              //  String urlToLog = remoteService.getLogFile(ipAddress);
                DvDeployment deployment = dvDeploymentService.getByDeviceId(deviceId);
                String deptId = deployment.getDeptId();
                dvRemoteCommand.setDeviceId(deviceId);
                dvRemoteCommand.setCommandType(5L);
                dvRemoteCommand.setIpAddress(ipAddress);
                dvRemoteCommand.setIssuedStatus(1L);
                dvRemoteCommand.setIssuedTime(DateUtils.getNowDate());
                dvRemoteCommand.setStatus(0);
                dvRemoteCommand.setDeptId(deptId);
                dvRemoteCommandService.insertDvRemoteCommand(dvRemoteCommand);
                /*cn.hutool.json.JSONObject param = JSONUtil.createObj();
                param.set("deviceId",deviceId);
                param.set("logDateSpan",logDateSpan);*/
               // getFileStream(request,response,urlToLog,deviceId,logDateSpan);
            
            
//        } catch (Exception e) {
//            logger.error("远程拉取日志路径失败：" + e);
//            return R.fail("远程拉取日志失败：请联系工作人员");
//
//    		
//        }
		return R.ok(messageCode);
    }

    // 4、远程自检
    @ApiOperation("远程自检")
    @PostMapping("/selfcheck")
    public R selfcheck(@RequestBody List<RemoteDto> remoteDteList){
        log.info("远程自检 请求参数 remoteDteList：{}", JSONObject.toJSONString(remoteDteList));
        remoteDteList.forEach(m ->{
        // 流水号
        m.setMessageCode(GenerateCodeUtils.getSequnce());
        m.setCommandType(6);
        String deviceId = m.getDeviceId();
        MqttPushClient client = mqttConfig.getDeviceIdMqttPushClient(deviceId);
        String json = JSON.toJSONString(m);
        R publish  = client.publish(0, false, deviceId, json);
        DvRemoteCommand dvRemoteCommand = new DvRemoteCommand();
        long issuedStatus = 1L;
        if (!publish.isSuccess()){
            issuedStatus = -1L;
            dvRemoteCommand.setIssuedErrrorMessage("远程自检消息推送失败");
        }
        String ipAddress = m.getIpAddress();
                DvDeployment deployment = dvDeploymentService.getByDeviceId(deviceId);
                String deptId = deployment.getDeptId();
                dvRemoteCommand.setDeviceId(deviceId);
                dvRemoteCommand.setCommandType(6L);
                dvRemoteCommand.setIpAddress(ipAddress);
                dvRemoteCommand.setIssuedStatus(issuedStatus);
                dvRemoteCommand.setIssuedTime(DateUtils.getNowDate());
                dvRemoteCommand.setStatus(0);
                dvRemoteCommand.setDeptId(deptId);
                dvRemoteCommandService.insertDvRemoteCommand(dvRemoteCommand);           
        } );
        return R.ok("远程自检消息已经推送");
    }

/*    public void getFileStream(HttpServletRequest request, HttpServletResponse response, String reqUrl, String deviceId, Integer logDateSpan) throws Exception {
        HttpURLConnection urlConnection = null;
        InputStream inputStream;
        try {
            log.info("获取附件文件 请求url：{}", reqUrl);
            URL url = new URL(reqUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("POST");
            urlConnection.setConnectTimeout(20000);
            urlConnection.setDoOutput(true);
            urlConnection.setDoInput(true);
            urlConnection.setUseCaches(false);
            urlConnection.setRequestProperty("Content-Type", "application/octet-stream; charset=UTF-8");
            urlConnection.connect();
            //设置请求体
            //HashMap map=new HashMap();
            //key-value的形式设置请求参数
            //map.put("key",logDateSpan);
            //String s = JSONObject.toJSONString(map);
            //urlConnection.setRequestProperty("deviceId",deviceId);
            //urlConnection.setRequestProperty("logDateSpan",logDateSpan.toString());
            JSONObject params = new JSONObject();
            params.put("deviceId",deviceId);
            params.put("logDateSpan",logDateSpan);
            String jsonStr = params.toString();
            OutputStream os = urlConnection.getOutputStream();
            os.write(jsonStr.getBytes("utf-8"));
            os.flush();
            os.close();
            inputStream = urlConnection.getInputStream();
            String ContentType = urlConnection.getContentType();
            if (ContentType.startsWith("application/json")) {
				throw new RuntimeException("获取文件异常");
			}
            log.info("获取附件文件 获取inputStream：{}", inputStream);
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            byte[] buf = new byte[4096];
            int length = bufferedInputStream.read(buf);
            ServletOutputStream out = response.getOutputStream();
            while (-1 != length) {
                out.write(buf, 0,length);
                length = bufferedInputStream.read(buf);
            }
            out.flush();
            out.close();
            inputStream.close();
            bufferedInputStream.close();
        } catch (Exception e) {
            System.out.println("getFile error: " + e);
            throw new Exception();
        } finally {
            if (null != urlConnection) {
                urlConnection.disconnect();
            }
        }
    }*/
    
//    @ApiOperation(value = "获取数据库中最新的日志文件")
//    @GetMapping("/getLogFile")
//    public R getLogFile(@RequestParam String messageCode,@RequestParam Integer dateSpan) throws IOException
//    {
//    DvSaveLogFile dvSaveLogFile=new DvSaveLogFile();
//    dvSaveLogFile.setMessageCode(messageCode);
//    dvSaveLogFile.setDateSpan(dateSpan);
//        DvSaveLogFile dvSaveLogFileRsp = dvSaveLogFileService.selectDvSaveLogFile(dvSaveLogFile);
//        if(dvSaveLogFileRsp==null){
//            return R.ok(null);
//        }
//        return R.ok(dvSaveLogFileRsp.getFileUrl());
//    }

    @ApiOperation(value = "获取数据库中最新的日志文件")
    @GetMapping("/getLogFile")
    public void getLogFile(
            HttpServletResponse response,
            @RequestParam String messageCode,Integer dateSpan,String fileDate
    ) throws IOException {
    	 DvSaveLogFile dvSaveLogFile=new DvSaveLogFile();
    	    dvSaveLogFile.setMessageCode(messageCode);
    	    dvSaveLogFile.setDateSpan(dateSpan);
    	    dvSaveLogFile.setFileDate(fileDate);
    	        DvSaveLogFile dvSaveLogFileRsp = dvSaveLogFileService.selectDvSaveLogFile(dvSaveLogFile);        // 文件路径
    	        if (dvSaveLogFileRsp!=null) {									
    	        File file = new File(dvSaveLogFileRsp.getFileUrl());

    	        //读取生成的PDF文件
    	        InputStream inputStream = null;
    	        OutputStream outputStream = null;

    	        try {
    	           if (file.exists()){
    	               inputStream = new FileInputStream(file);
    	               outputStream = new BufferedOutputStream(response.getOutputStream());
    	               byte[] bytes = new byte[1024];
    	               int len;
    	               while ((len = inputStream.read(bytes)) != -1){
    	                   response.getOutputStream().write(bytes,0,len);
    	               }
    	               outputStream.flush();
    	               outputStream.close();
    	               inputStream.close();
    	           }
    	            } catch (FileNotFoundException e) {
    	                e.printStackTrace();
    	            } catch (IOException e) {
    	                e.printStackTrace();
    	        }finally {
 	               outputStream.close();
 	               inputStream.close();
				}
    	   }
    }
    
}
